package com.it.component;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author TBH
 * @date 2025-05-01 23:26:31
 * @desc
 */
@Component
@RequiredArgsConstructor
public class AuthorizationCache {

    private final StringRedisTemplate restTemplate;
    private static final String roles_path = "Authorization:Roles:";
    private static final String permission_path = "Authorization:Permissions:";

    public List<String> getRoles(Object loginId) {
        List<String> roles = new ArrayList<>();
        String roleJson = restTemplate.opsForValue().get(roles_path + loginId);
        if (StringUtils.isNotEmpty(roleJson)) {
            roles = JSONUtil.toList(roleJson, String.class);
        }
        return roles;
    }

    public void setRoles(Object loginId, List<String> roles) {
        if (CollectionUtil.isNotEmpty(roles)) {
            String rolesJson = JSONUtil.toJsonStr(roles);
            restTemplate.opsForValue().set(roles_path + loginId, rolesJson, 5, TimeUnit.MINUTES);
        }
    }

    public List<String> getPermissions(Object loginId) {
        List<String> permissions = new ArrayList<>();
        String roleJson = restTemplate.opsForValue().get(permission_path + loginId);
        if (StringUtils.isNotEmpty(roleJson)) {
            permissions = JSONUtil.toList(roleJson, String.class);
        }
        return permissions;
    }

    public void setPermissions(Object loginId, List<String> permissions) {
        if (CollectionUtil.isNotEmpty(permissions)) {
            String permissionsJson = JSONUtil.toJsonStr(permissions);
            restTemplate.opsForValue().set(permission_path + loginId, permissionsJson, 5, TimeUnit.MINUTES);
        }
    }

    public void clearRoles() {
        clearKey("Authorization:Roles:*");
    }

    public void clearPermissions() {
        clearKey("Authorization:Permissions:*");
    }


    public void clearKey(String key) {
        restTemplate.execute((RedisCallback<Void>) connection -> {
            Cursor<byte[]> cursor = connection.scan(
                    ScanOptions.scanOptions()
                            .match(key)
                            .count(100)
                            .build());
            while (cursor.hasNext()) {
                connection.del(cursor.next());
            }
            return null;
        });
    }

    public void clearKeys(String[] keys) {
        for (String key : keys) {
            clearKey(key);
        }
    }
}